from flask_restful import Resource, reqparse, marshal_with, inputs
from flask import current_app, jsonify
from ..models import Application, User, Mission
from flask_jwt_extended import jwt_required, current_user
from .dto import application_dto
from ..error import InvalidUsage
from .util import remove_none_fields

parser = reqparse.RequestParser()
parser.add_argument('description', type=str)
parser.add_argument('score', type=float)


class ApplicationService(Resource):

    @jwt_required()
    @marshal_with(application_dto)
    def get(self, app_id):
        app = Application.query_by_id(app_id)
        if app is None:
            raise InvalidUsage('Application not found', status_code=404)
        return app

    @jwt_required()
    @marshal_with(application_dto)
    def post(self, mission_id):
        args = remove_none_fields(parser.parse_args())
        mission = Mission.query_by_id(mission_id)
        if mission is None:
            raise InvalidUsage('Mission not found', 404)
        app = Application(**args, mission=mission,
                          applier=current_user, state=0)
        app.save()
        return app

    @jwt_required()
    @marshal_with(application_dto)
    def put(self, app_id):
        args = remove_none_fields(parser.parse_args())
        app = Application.query_by_id(app_id)
        if app is None:
            raise InvalidUsage('Application not found', status_code=404)
        if app.applier_id != current_user.id:
            raise InvalidUsage('You are not the applier', status_code=401)
        return Application.update_by_id(app_id, args)

    @jwt_required()
    def delete(self, app_id):
        app = Application.query_by_id(app_id)
        if app is None:
            raise InvalidUsage('Application not found', status_code=404)
        if app.applier_id != current_user.id:
            raise InvalidUsage('You are not the applier', status_code=401)

        # 退回待申请状态
        Mission.update_by_id(app.mission_id, {'state': 0})
        Application.delete_app(app)
        return jsonify({'message': 'Application deleted'})


class ApplicationDeclineService(Resource):
    @jwt_required()
    # @marshal_with(application_dto)
    def get(self, app_id):
        app = Application.query_by_id(app_id)
        if app is None:
            raise InvalidUsage('Application not found', status_code=404)
        if app.mission.owner_id != current_user.id:
            raise InvalidUsage(
                'You are not the mission owner', status_code=401)
        if app.state != 0:
            raise InvalidUsage('Application already handled', status_code=401)
        Application.update_by_id(app_id, {'state': 1})
        return


class ApplicationAcceptService(Resource):
    @jwt_required()
    # @marshal_with(application_dto)
    def get(self, app_id):
        app = Application.query_by_id(app_id)
        if app is None:
            raise InvalidUsage('Application not found', status_code=404)
        if app.mission.owner_id != current_user.id:
            raise InvalidUsage(
                'You are not the mission owner', status_code=401)
        if app.state != 0:
            raise InvalidUsage('Application already handled', status_code=401)
        Application.update_by_id(app_id, {'state': 2})
        Mission.accept_one(app.mission_id)
        return


class ApplicationCompleteService(Resource):
    @jwt_required()
    @marshal_with(application_dto)
    def put(self, app_id):
        args = remove_none_fields(parser.parse_args())
        current_app.logger.info("args: {}".format(args))
        app = Application.query_by_id(app_id)
        if app is None:
            raise InvalidUsage('申请不存在', status_code=404)
        if app.applier_id != current_user.id:
            raise InvalidUsage('当前用户不是申请者', status_code=401)
        if app.state != 2:
            raise InvalidUsage('申请未被接受', status_code=401)
        User.update_by_id(app.applier_id, {
                          'credit': app.applier.credit + app.mission.credit_per_people})
        User.update_by_id(app.mission.owner_id,
                          {'credit': app.mission.owner.credit - app.mission.credit_per_people})
        app = Application.update_by_id(
            app_id, {'state': 3, 'score': args['score']})
        # 新增一个完成
        Mission.complete_one(app.mission_id)
        return app
